home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <time.h>
- #include <ctype.h>
- #if (defined(UNIX) || defined(MICROSOFT))
- #include <sys/types.h>
- #endif
- #include "bm.h"
-
- struct addr *addrecip();
- char *ptime();
-
- /* send a message */
- dosmtpsend(mfp,toargs,nargs,subject)
- FILE *mfp;
- char *toargs[];
- int nargs;
- char *subject;
- {
- char smtp_subject[LINELEN],
- tstring[LINELEN];
- char *tmpnam();
- FILE *fpin;
- char *p;
- char *tf = "bmXXXXXX"; /* temp file name */
- int c;
- int n;
- long sequence;
- struct addr *tolist,*tp;
- register FILE *tfile;
- time_t t;
-
-
- if (nargs == 0) {
- printf("No recpients\n");
- return 0;
- }
- fpin = mfp;
- if ((tolist = make_tolist(nargs,toargs)) == NULLADDR) {
- printf("Send aborted\n");
- return 0;
- }
-
- sequence = get_msgid();
-
- time(&t);
- mktemp(tf);
- /* open textfile for write */
- if ((tfile = fopen(tf,"w+")) == NULLFILE) {
- perror(tf);
- del_addrlist(tolist);
- return 1;
- }
-
- if (!qflag) {
- /* write RFC822-compatible headers using above information */
- fprintf(tfile,"Date: %s",ptime(&t));
- fprintf(tfile,"Message-Id: <%ld@%s>\n",sequence,hostname);
- fprintf(tfile,"From: %s@%s",username,hostname);
- if (fullname != NULLCHAR && *fullname != '\0')
- fprintf(tfile," (%s)",fullname);
- fprintf(tfile,"\n");
- if (replyto != NULLCHAR && *replyto != '\0')
- fprintf(tfile,"Reply-To: %s\n",replyto);
- strcpy(tstring,"To: ");
- for (tp = tolist; tp != NULLADDR; tp = tp->next) {
- strcat(tstring,tp->user);
- if (tp->host != NULLCHAR || *tp->host != '\0') {
- strcat(tstring,"@");
- strcat(tstring,tp->host);
- }
- n = strlen(tstring);
- if (tp->next) {
- if (n > 50) {
- fprintf(tfile,"%s,\n\t",tstring);
- if (tty) printf("%s,\n ",tstring);
- *tstring = '\0';
- } else
- strcat(tstring,", ");
- }
- }
- fprintf(tfile,"%s\n",tstring);
- if (tty) printf("%s\n",tstring);
-
- *smtp_subject = '\0';
- if (subject == NULL && tty) {
- /* prompt and get Subject: */
- printf("Subject: ");
- gets(smtp_subject);
- } else {
- strcpy(smtp_subject,subject);
- if(tty) printf("Subject: %s\n",smtp_subject);
- }
- fprintf(tfile,"Subject: %s\n",smtp_subject);
- fprintf(tfile,"\n"); /* add empty line as separator */
- }
-
- if (!tty && fpin == NULLFILE)
- fpin = stdin;
-
- if (fpin != NULLFILE ) {
- while((c = getc(fpin)) != EOF)
- if(putc(c,tfile) == EOF)
- break;
- if (ferror(tfile)) {
- perror("tmp file");
- (void) fclose(tfile);
- (void) unlink(tf);
- return 1;
- }
- } else {
- /* sending a message not from a file */
- /* copy text from console to the file */
- printf("\nType message text. Enter a '.' or ctrl/D in column one to end.");
- printf("\nCommands: ~p - redisplay msg, ~e - invoke editor, ~? - help\n\n");
- for(;;) {
- /* read line from console ie stdin */
- if (gets(tstring) == NULLCHAR)
- break;
- rip(tstring);
- if(strcmp(tstring,".") == 0 || tstring[0] == '\004')
- break;
- if (*tstring == '~' ) {
- switch(tstring[1]) {
- case 'p':
- /* Print the message so far */
- fseek(tfile,0L,0);
- while (fgets(tstring,sizeof(tstring),tfile) != NULLCHAR)
- fputs(tstring,stdout);
- break;
- case 'e':
- /* Drop into editor */
- (void) fclose(tfile);
- if (editor == NULLCHAR) {
- printf("No editor defined\n");
- break;
- }
- sprintf(tstring,"%s %s",editor,tf);
- /* call editor to enter message text */
- if (system(tstring))
- printf("unable to invoke editor\n");
- tfile = fopen(tf,"a+");
- break;
- case 'q':
- (void) fclose(tfile);
- (void) unlink(tf);
- printf("Abort\n");
- return 0;
- case 'r':
- {
- FILE *infl;
- p = &tstring[2];
- while(*p == ' ' || *p == '\t')
- p++;
- if (*p == '\0')
- printf("No file name specified\n");
- else
- if((infl = fopen(p,"r")) == NULLFILE)
- printf("No such file\n");
- else {
- printf("Reading file %s\n",p);
- while((c = getc(infl)) != EOF)
- if(putc(c,tfile) == EOF)
- break;
- if (ferror(tfile)) {
- perror("tmp file");
- (void) fclose(tfile);
- (void) unlink(tf);
- return 1;
- }
- (void) fclose(infl);
- }
-
- break;
- }
- case 'm':
- {
- int msg;
- p = &tstring[2];
- while(*p == ' ' || *p == '\t')
- p++;
- if (*p == '\0')
- msg = current;
- else
- msg = atoi(p);
- if (mfile == NULLFILE || msg < 1 || msg > nmsgs)
- printf("no such message\n");
- else {
- printf("Inserting message %d\n",msg);
- msgtofile(msg,tfile,0);
- }
- break;
- }
- case '~':
- fprintf(tfile,"%s\n",&tstring[1]);
- break;
- case '?':
- printf("~e - Invoke Editor\n");
- printf("~p - Display message buffer\n");
- printf("~q - Abort this message\n");
- printf("~r file - Read file into buffer\n");
- printf("~m msg - message into buffer\n");
- printf("~~ - Enter a ~ into message\n");
- break;
- default:
- printf("Unknown ~ escape. ~? for help\n");
- }
- printf("(continue)\n");
- } else
- fprintf(tfile,"%s\n",tstring);
- }
- printf("EOF\n");
-
- }
- queuejob(tfile,tolist);
- recordmsg(tfile,tolist->user); /* save copy for sender */
- (void) fclose(tfile);
- del_addrlist(tolist);
- (void) unlink(tf);
- return 0;
- }
-
- /* forward a message in its orginal form */
- bouncemsg(mfp,toargs,nargs)
- FILE *mfp;
- char *toargs[];
- int nargs;
- {
- struct addr *list;
- if (nargs == 0) {
- printf("No recpients\n");
- } else if ((list = make_tolist(nargs,toargs)) == NULLADDR) {
- printf("Bad to list\n");
- } else {
- queuejob(mfp,list);
- del_addrlist(list);
- }
- return 0;
- }
-
- /* Return Date/Time in Arpanet format in passed string */
- /* Print out the time and date field as
- * "DAY day MONTH year hh:mm:ss ZONE"
- */
- char *
- ptime(t)
- long *t;
- {
- register struct tm *ltm;
- struct tm *localtime();
- static char tz[4];
- static char str[40];
- extern char *getenv();
- char *p;
- static char *days[7] = {
- "Sun","Mon","Tue","Wed","Thu","Fri","Sat" };
-
- static char *months[12] = {
- "Jan","Feb","Mar","Apr","May","Jun",
- "Jul","Aug","Sep","Oct","Nov","Dec" };
-
- /* Read the system time */
- ltm = localtime(t);
-
- if (*tz == '\0')
- if ((p = getenv("TZ")) == NULL)
- strcpy(tz,"GMT");
- else
- strncpy(tz,p,3);
-
- /* rfc 822 format */
- sprintf(str,"%s, %.2d %s %02d %02d:%02d:%02d %.3s\n",
- days[ltm->tm_wday],
- ltm->tm_mday,
- months[ltm->tm_mon],
- ltm->tm_year,
- ltm->tm_hour,
- ltm->tm_min,
- ltm->tm_sec,
- tz);
- return(str);
- }
-
- /* save copy in the record file */
- recordmsg(dfile,to)
- FILE *dfile;
- char *to;
- {
- register int c;
- FILE *fp;
- time_t t;
-
- if (record == NULLCHAR)
- return 1;
- fseek(dfile,0L,0);
- if ((fp = fopen(record,"a")) == NULLFILE) {
- printf("Unable to append to %s\n",record);
- } else {
- (void) time(&t);
- fprintf(fp,"From %s %s",to,ctime(&t));
- while((c = getc(dfile)) != EOF)
- if(putc(c,fp) == EOF)
- break;
- if (ferror(fp)) {
- (void) fclose(fp);
- return 1;
- }
- (void) fclose(fp);
- }
- return 0;
- }
-
- /* place a mail job in the outbound queue */
- int
- queuejob(dfile,tolist)
- FILE *dfile;
- struct addr *tolist;
- {
- FILE *fp;
- char tmpstring[50];
- register struct addr *tp,*sp;
- char prefix[9];
- int c;
- long id;
-
- for (tp = tolist; tp != NULLADDR; tp = tp->next) {
- if (tp->sent)
- continue;
- fseek(dfile,0L,0);
- id = get_msgid();
- sprintf(prefix,"%ld",id);
- (void) mlock(mqueue,prefix);
- sprintf(tmpstring,"%s/%s.txt",mqueue,prefix);
- if((fp = fopen(tmpstring,"w")) == NULLFILE) {
- printf("unable to open %s\n",tmpstring);
- (void) rmlock(mqueue,prefix);
- return 1;
- }
- while((c = getc(dfile)) != EOF)
- if(putc(c,fp) == EOF)
- break;
- if (ferror(fp)) {
- (void) fclose(fp);
- (void) rmlock(mqueue,prefix);
- return 1;
- }
- (void) fclose(fp);
- sprintf(tmpstring,"%s/%s.wrk",mqueue,prefix);
- if((fp = fopen(tmpstring,"w")) == NULLFILE) {
- (void) rmlock(mqueue,prefix);
- return 1;
- }
- fprintf(fp,"%s\n%s@%s\n",tp->host,username,hostname);
- fprintf(fp,"%s@%s\n",tp->user,tp->host);
- tp->sent++;
- /* find and other addresses to the same host */
- for (sp = tp->next; sp != NULLADDR; sp = sp->next) {
- if (sp->sent)
- continue;
- if (strcmp(tp->host,sp->host) == 0) {
- fprintf(fp,"%s@%s\n",sp->user,sp->host);
- sp->sent++;
- }
- }
- (void) fclose(fp);
- (void) rmlock(mqueue,prefix);
- }
- return 0;
- }
-
- #define SKIPWORD(X) while(*X && *X!=' ' && *X!='\t' && *X!='\n' && *X!= ',') X++;
- #define SKIPSPACE(X) while(*X ==' ' || *X =='\t' || *X =='\n' || *X == ',') X++;
-
- /* check for and alias and expand alais into a address list */
- struct addr *
- expandalias(head, user)
- struct addr **head;
- char *user;
- {
- FILE *fp;
- register char *s,*p,*h;
- int inalias;
- struct addr *tp;
- char buf[LINELEN];
-
- fp = fopen(alias, "r");
-
- /* no alias file found */
- if (fp == NULLFILE)
- return addrecip(head, user, hostname);
-
- inalias = 0;
- while (fgets(buf,LINELEN,fp) != NULLCHAR) {
- p = buf;
- if ( *p == '#' || *p == '\0')
- continue;
- rip(p);
-
- /* if not in an matching entry skip continuation lines */
- if (!inalias && isspace(*p))
- continue;
-
- /* when processing an active alias check for a continuation */
- if (inalias) {
- if (!isspace(*p))
- break; /* done */
- } else {
- s = p;
- SKIPWORD(p);
- *p++ = '\0'; /* end the alias name */
- if (strcmp(s,user) != 0)
- continue; /* no match go on */
- inalias = 1;
- }
-
- /* process the recipients on the alias line */
- SKIPSPACE(p);
- while(*p != '\0' && *p != '#') {
- s = p;
- SKIPWORD(p);
- if (*p != '\0')
- *p++ = '\0';
- /* find hostname */
- if ((h = strchr(s,'@')) != NULLCHAR)
- *h++ = '\0';
- else
- h = hostname;
- tp = addrecip(head,s,h);
- SKIPSPACE(p);
- }
- }
- (void) fclose(fp);
-
- if (inalias) /* found and processed and alias. */
- return tp;
-
- /* no alias found treat as a local address */
- return addrecip(head, user, hostname);
- }
-
- /* convert a arg list to an list of address structures */
- struct addr *
- make_tolist(argc,argv)
- int argc;
- char *argv[];
- {
- struct addr *tolist, *tp;
- char *user, *host;
- int i;
- tolist = NULLADDR;
- for (i = 0; i < argc; i++) {
- user = argv[i];
- if ((host = strchr(user ,'@')) != NULLCHAR) {
- *host++ = '\0';
- /* if it matches our host name */
- if (stricmp(host,hostname) == 0)
- host = NULLCHAR;
- }
-
- if (host == NULLCHAR) /* a local address */
- tp = expandalias(&tolist,user);
- else /* a remote address */
- tp = addrecip(&tolist, user, host);
-
- if (tp == NULLADDR) {
- printf("Out of memory\n");
- del_addrlist(tolist);
- return NULLADDR;
- }
- }
- return tolist;
- }
-
- /* delete a list of mail addresses */
- del_addrlist(list)
- struct addr *list;
- {
- struct addr *tp, *tp1;;
- for (tp = list; tp != NULLADDR; tp = tp1) {
- tp1 = tp->next;
- if (tp->user != NULLCHAR);
- free(tp->user);
- if (tp->host != NULLCHAR);
- free(tp->host);
- (void) free((char *)tp);
- }
- }
-
- /* add an address to the from of the list pointed to by head
- ** return NULLADDR if out of memory.
- */
- struct addr *
- addrecip(head,user,host)
- struct addr **head;
- char *user, *host;
- {
- register struct addr *tp;
-
- tp = (struct addr *)calloc(1,sizeof(struct addr));
- if (tp == NULLADDR)
- return NULLADDR;
-
- tp->next = NULLADDR;
-
- /* allocate storage for the user's login */
- if ((tp->user = malloc((unsigned)strlen(user)+1)) == NULLCHAR) {
- (void) free((char *)tp);
- return NULLADDR;
- }
- strcpy(tp->user,user);
-
- /* allocate storage for the host name */
- if (host != NULLCHAR)
- if ((tp->host = malloc((unsigned)strlen(host)+1)) == NULLCHAR) {
- (void) free(tp->user);
- (void) free((char *)tp);
- return NULLADDR;
- }
- strcpy(tp->host,host);
-
- /* add entry to front of existing list */
- if (*head == NULLADDR)
- *head = tp;
- else {
- tp->next = *head;
- *head = tp;
- }
- return tp;
-
- }
-